package com.yuxl.admin.manager.auth.core.service;

import cn.hutool.core.collection.CollUtil;
import com.yuxl.admin.manager.auth.core.entity.*;
import com.yuxl.admin.manager.auth.core.repository.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Set;


@Service
@RequiredArgsConstructor
public class AuthRoleService {

    private final AuthRoleRepository authRoleRepository;
    private final AuthUserRepository authUserRepository;
    private final AuthOperateRepository authOperateRepository;
    private final AuthInterfaceRepository authInterfaceRepository;
    private final AuthMenuRepository authMenuRepository;
    private final AuthUserRoleRepository authUserRoleRepository;
    private final AuthRolePowerRepository authRolePowerRepository;
    public Mono<AuthRole> findById(Long id) {
        return authRoleRepository.findById(id);
    }

    public Flux<AuthRole> findAll() {
        return authRoleRepository.findAll();
    }

    public Mono<AuthRole> createRole(AuthRole role) {
        return authRoleRepository.save(role);
    }

    public Mono<AuthRole> updateRole(Long id, AuthRole role) {
        return authRoleRepository.findById(id)
                .flatMap(existingRole -> {
                    existingRole.setMark(role.getMark());
                    existingRole.setName(role.getName());
                    return authRoleRepository.save(existingRole);
                });
    }

    public Mono<Boolean> deleteRole(Long id) {
        return authRoleRepository.deleteById(id).thenReturn(true);
    }

    public Flux<AuthRole> findRolesByUserId(Long userId) {
        return authUserRoleRepository.findByUserId(userId)
                .flatMap(userRole -> authRoleRepository.findById(userRole.getRoleId()));
    }

    public Flux<AuthRole> findByMark(String mark) {
        return authRoleRepository.findByMark(mark);
    }

    public Flux<AuthRole> findAll(Integer page, Integer size) {
        if (page != null && size != null) {
            return authRoleRepository.findAll()
                    .skip((long) page * size)
                    .take(size);
        }
        return authRoleRepository.findAll();
    }

    /**
     * 获取角色的用户
     * @param roleId 角色ID
     * @param roleMark 角色标记
     * @return 拥有指定角色的用户列表
     */
    public Flux<AuthUser> getUsersByRole(
            Long roleId,
            String roleMark) {
        if (roleId != null) {
            return authUserRoleRepository.findByRoleId(roleId)
                    // 根据角色ID查找用户角色关系
                    .flatMap(userRole -> authUserRepository.findById(userRole.getUserId()));
            // 根据用户ID查找用户
        } else if (roleMark != null) {
            return authRoleRepository.findByMark(roleMark)
                    // 根据角色标记查找角色
                    .flatMap(role -> authUserRoleRepository.findByRoleId(role.getId()))
                    // 根据角色ID查找用户角色关系
                    .flatMap(userRole -> authUserRepository.findById(userRole.getUserId()));
            // 根据用户ID查找用户
        } else {
            return Flux.empty();
            // 如果没有提供roleId或roleMark，返回空结果
        }
    }

    /**
     * 获取角色的接口
     * @param roleId 角色ID
     * @param roleMark 角色标记
     * @return 拥有指定角色的接口列表
     */
    public Flux<AuthInterface> getInterfacesByRole(
            Long roleId,
            String roleMark) {
        if (roleId != null) {
            return authRolePowerRepository.findByRoleId(roleId)
                    // 根据角色ID查找角色接口关系
                    .flatMap(roleInterface -> authInterfaceRepository.findById(roleInterface.getPowerId()));
            // 根据接口ID查找接口
        } else if (roleMark != null) {
            return authRoleRepository.findByMark(roleMark)
                    // 根据角色标记查找角色
                    .flatMap(role -> authRolePowerRepository.findByRoleId(role.getId()))
                    // 根据角色ID查找用户角色关系
                    .flatMap(roleInterface -> authInterfaceRepository.findById(roleInterface.getPowerId()));
            // 根据用户ID查找用户
        } else {
            return Flux.empty();
            // 如果没有提供roleId或roleMark，返回空结果
        }
    }

    public Flux<AuthInterface> getInterfacesByRoleIds(Set<Long> roleIds) {
        if (CollUtil.isNotEmpty(roleIds)) {
            return authRolePowerRepository.findInterfaceIdByRoleIdIn(roleIds)
                    // 根据角色ID查找角色菜单关系
                    .flatMap(roleMenu -> authInterfaceRepository.findById(roleMenu.getPowerId()));
            // 根据菜单ID查找菜单
        } else {
            return Flux.empty();
            // 如果没有提供roleId或roleMark，返回空结果
        }
    }

    /**
     * 获取角色的菜单
     * @param roleId 角色ID
     * @param roleMark 角色标记
     * @return 拥有指定角色的菜单列表
     */
    public Flux<AuthMenu> getMenusByRole(
            Long roleId,
            String roleMark) {
        if (roleId != null) {
            return authRolePowerRepository.findByRoleId(roleId)
                    // 根据角色ID查找角色菜单关系
                    .flatMap(roleMenu -> authMenuRepository.findById(roleMenu.getPowerId()));
            // 根据菜单ID查找菜单
        } else if (roleMark != null) {
            return authRoleRepository.findByMark(roleMark)
                    // 根据角色标记查找角色
                    .flatMap(role -> authRolePowerRepository.findByRoleId(role.getId()))
                    // 根据角色ID查找用户角色关系
                    .flatMap(roleMenu -> authMenuRepository.findById(roleMenu.getPowerId()));
            // 根据用户ID查找用户
        } else {
            return Flux.empty();
            // 如果没有提供roleId或roleMark，返回空结果
        }
    }

    public Flux<AuthMenu> getMenusByRoleIds(Set<Long> roleIds) {
        if (CollUtil.isNotEmpty(roleIds)) {
            return authRolePowerRepository.findMenuIdByRoleIdIn(roleIds)
                    // 根据角色ID查找角色菜单关系
                    .flatMap(roleMenu -> authMenuRepository.findById(roleMenu.getPowerId()));
            // 根据菜单ID查找菜单
        } else {
            return Flux.empty();
            // 如果没有提供roleId或roleMark，返回空结果
        }
    }

    /**
     * 获取角色的操作
     * @param roleId 角色ID
     * @param roleMark 角色标记
     * @return 拥有指定角色的操作列表
     */
    public Flux<AuthOperate> getOperatesByRole(
            @RequestParam(required = false) Long roleId,
            @RequestParam(required = false) String roleMark) {
        if (roleId != null) {
            return authRolePowerRepository.findByRoleId(roleId)
                    // 根据角色ID查找角色操作关系
                    .flatMap(roleOperate -> authOperateRepository.findById(roleOperate.getPowerId()));
            // 根据操作ID查找操作
        } else if (roleMark != null) {
            return authRoleRepository.findByMark(roleMark)
                    // 根据角色标记查找角色
                    .flatMap(role -> authRolePowerRepository.findByRoleId(role.getId()))
                    // 根据角色ID查找用户角色关系
                    .flatMap(roleOperate -> authOperateRepository.findById(roleOperate.getPowerId()));
            // 根据用户ID查找用户
        } else {
            return Flux.just();
            // 如果没有提供roleId或roleMark，返回空结果
        }
    }

    public Flux<AuthOperate> getOperatesByRoleIds(Set<Long> roleIds) {
        if (CollUtil.isNotEmpty(roleIds)) {
            return authRolePowerRepository.findOperateIdByRoleIdIn(roleIds)
                    // 根据角色ID查找角色操作关系
                    .flatMap(roleMenu -> authOperateRepository.findById(roleMenu.getPowerId()));
            // 根据菜单ID查找菜单
        } else {
            return Flux.empty();
            // 如果没有提供roleId或roleMark，返回空结果
        }
    }
}
